package com.north.light.libmusicplayerx.ipc

import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.Handler
import android.os.IBinder
import android.os.Looper
import com.north.light.libmusicplayerx.LibPXMusicBinder
import com.north.light.libmusicplayerx.LibPXMusicListener
import com.north.light.libmusicplayerx.LibPXMusicProgressListener
import com.north.light.libmusicplayerx.servie.LibMPXService
import com.north.light.libmusicplayerx.servie.base.LibMPXBaseServiceCompat
import com.north.light.libmusicplayerx.utils.KtLogUtil
import java.io.Serializable

/**
 * FileName: IPCPxMusic
 * Author: lzt
 * Date: 2023/3/9 10:51
 */
class IPCPxMusic : Serializable {
    private var mBinder: LibPXMusicBinder? = null

    //重连handler
    private val mHandler: Handler = Handler(Looper.getMainLooper())
    private val mConnectInterval = 2000L

    private lateinit var mContext: Context

    //是否连接成功
    private var mConnected = false

    companion object {
        @JvmStatic
        fun getInstance(): IPCPxMusic {
            return SingleHolder.mInstance
        }
    }

    object SingleHolder {
        val mInstance = IPCPxMusic()
    }

    private val serviceConnection = object : ServiceConnection {
        override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
            try {
                mBinder = LibPXMusicBinder.Stub.asInterface(service)
                mBinder?.init()
                mBinder?.setLibPXMusicListener(musicListener)
                mBinder?.setLibPXMusicProgressListener(musicProgressListener)
                mConnected = true
                KtLogUtil.d("onServiceConnected success")
            } catch (e: Exception) {
                e.printStackTrace()
                mConnected = false
                KtLogUtil.d("onServiceConnected error: " + e.message)
            }
        }

        override fun onServiceDisconnected(name: ComponentName?) {
            try {
                mBinder?.removeLibPXMusicListener(musicListener)
                mBinder?.removeLibPXMusicProgressListener(musicProgressListener)
                mBinder = null
                mConnected = false
                KtLogUtil.d("onServiceDisconnected success")
            } catch (e: Exception) {
                e.printStackTrace()
                mConnected = false
                KtLogUtil.d("onServiceDisconnected error: " + e.message)
            }
            reConnectService()
        }
    }

    private val musicProgressListener = object : LibPXMusicProgressListener.Stub() {
        override fun progress(url: String?, current: Int, total: Int) {
            KtLogUtil.d("ipc px music progress")
        }

        override fun buffering(url: String?, current: Int, total: Int) {
            KtLogUtil.d("ipc px music buffering")
        }
    }

    private val musicListener = object : LibPXMusicListener.Stub() {
        override fun init() {
            KtLogUtil.d("ipc px music init")
        }

        override fun play(url: String?) {
            KtLogUtil.d("ipc px music play")
        }

        override fun pause(url: String?) {
            KtLogUtil.d("ipc px music pause")
        }

        override fun resume(url: String?) {
            KtLogUtil.d("ipc px music resume")
        }

        override fun stop(url: String?) {
            KtLogUtil.d("ipc px music stop")
        }

        override fun finish(url: String?) {
            KtLogUtil.d("ipc px music finish")
        }

        override fun needToInit() {
            KtLogUtil.d("ipc px music needToInit")
        }
    }

    /**
     * 重新连接服务
     * */
    private fun reConnectService() {
        mHandler.removeCallbacksAndMessages(null)
        mHandler.postDelayed(
            Runnable {
                startService(1)
            }, mConnectInterval
        )
    }

    /**
     * 启动服务并且绑定
     * @param type 启动类型:0默认启动 1重新连接
     * */
    private fun startService(type: Int) {
        try {
            val intent = Intent(mContext, LibMPXService::class.java)
            LibMPXBaseServiceCompat.startService(mContext, intent)
            mContext.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE)
        } catch (e: Exception) {
            e.printStackTrace()
            KtLogUtil.d("startService error type:${type}--" + e.message)
        }
    }

    /**
     * 停止服务
     * */
    private fun stopService(type: Int = 0) {
        try {
            val intent = Intent(mContext, LibMPXService::class.java)
            mContext.unbindService(serviceConnection)
            mContext.stopService(intent)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }


    //外部调用------------------------------------------------------------------------------

    /**
     * 初始化--必须在application调用
     * */
    fun init(context: Context) {
        mContext = context.applicationContext
        startService(0)
    }

    /**
     * 输出一个日志
     * */
    fun log(message: String) {
        try {
            mBinder?.log(message)
            KtLogUtil.d("log:${message}")
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    /**
     * 播放音频
     * */
    fun play(url: String) {
        try {
            mBinder?.play(url)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    fun playAsset(resId: String) {
        try {
            mBinder?.playAsset(resId)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    /**
     * 停止
     * */
    fun stop() {
        try {
            mBinder?.stop()
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    /**
     * 恢复
     * */
    fun resume() {
        try {
            mBinder?.resume()
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    /**
     * 暂停
     * */
    fun pause() {
        try {
            mBinder?.pause()
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    /**
     * 释放--调用以后，需要重新init
     * */
    fun release() {
        try {
            mBinder?.release()
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    //状态相关-----------------------------------------------------------------------------


    /**
     * 是否播放中
     * */
    fun isPlaying(): Boolean {
        return try {
            mBinder?.isPlaying ?: false
        } catch (e: Exception) {
            e.printStackTrace()
            true
        }
    }

    //进度相关-----------------------------------------------------------------------------

    /**
     * 拖动进度
     * */
    fun seekTo(progress: Int) {
        try {
            mBinder?.seekTo(progress)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    /**
     * 获取进度
     * */
    fun getProgress(): Int {
        return try {
            mBinder?.progress ?: 0
        } catch (e: Exception) {
            e.printStackTrace()
            0
        }
    }

    /**
     * 获取总播放时长
     * */
    fun getDuration(): Int {
        return try {
            mBinder?.duration ?: 0
        } catch (e: Exception) {
            e.printStackTrace()
            0
        }
    }
}